﻿using System;
using System.Collections;
using System.IO;
using System.Text;
using System.Xml;
using MPMovieCatalog.Domain;
using MPMovieCatalog.Util;

namespace MPMovieCatalog.Export
{
    public class AMCExporter : Exporter
    {

        public AMCExporter(ArrayList movies, string fileName, string encodingName)
            : base(ResourceUtils.GetString("amcExport", 4), movies, fileName)
        {
            EncodingName = encodingName;
        }

        public string EncodingName { get; set; }

        protected override void Export()
        {
            XmlDocument xmlDocument = new XmlDocument();

            XmlElement amcXml = xmlDocument.CreateElement("AntMovieCatalog");
            xmlDocument.AppendChild(amcXml);

            XmlElement catalogXml = xmlDocument.CreateElement("Catalog");
            amcXml.AppendChild(catalogXml);

            XmlElement contentsXml = xmlDocument.CreateElement("Contents");
            catalogXml.AppendChild(contentsXml);

            int i = 0;
            foreach (MovieInfo movie in Movies)
            {
                OnProgress(++i);
                XmlElement movieXml = xmlDocument.CreateElement("Movie");
                contentsXml.AppendChild(movieXml);

                movieXml.Attributes.Append(CreateAttribute(xmlDocument, "Number", i.ToString()));
                movieXml.Attributes.Append(CreateAttribute(xmlDocument, "Checked", "True"));

                if (!string.IsNullOrEmpty(movie.IMDBRating) && !movie.IMDBRating.Equals("unknown"))
                {
                    movieXml.Attributes.Append(CreateAttribute(xmlDocument, "Rating", movie.IMDBRating.Replace(',', '.')));
                }

                string originalTitle, translatedTitle, formattedTitle;
                ParseTitle(movie.Name, out originalTitle, out translatedTitle, out formattedTitle);

                movieXml.Attributes.Append(CreateAttribute(xmlDocument, "OriginalTitle", originalTitle));
                movieXml.Attributes.Append(CreateAttribute(xmlDocument, "TranslatedTitle", translatedTitle));
                movieXml.Attributes.Append(CreateAttribute(xmlDocument, "FormattedTitle", formattedTitle));

                movieXml.Attributes.Append(CreateAttribute(xmlDocument, "Director", movie.Director));
                movieXml.Attributes.Append(CreateAttribute(xmlDocument, "Category", GenerateList(movie.Genres)));
                movieXml.Attributes.Append(CreateAttribute(xmlDocument, "Year", movie.Year));
                movieXml.Attributes.Append(CreateAttribute(xmlDocument, "Length", movie.Runtime));
                movieXml.Attributes.Append(CreateAttribute(xmlDocument, "Actors", GenerateList(movie.Actors)));
                movieXml.Attributes.Append(CreateAttribute(xmlDocument, "Description", FormatDescription(movie.Description)));

                if (movie.Picture != null && movie.Picture != string.Empty)
                {
                    string pictureFileName = string.Format(@"{0}\{1}_{2}.jpg", Path.GetDirectoryName(FileName), Path.GetFileNameWithoutExtension(FileName), i);
                    File.WriteAllBytes(pictureFileName, Convert.FromBase64String(movie.Picture));
                    movieXml.Attributes.Append(CreateAttribute(xmlDocument, "Picture", Path.GetFileName(pictureFileName)));
                }

            }

            StreamWriter sw = new StreamWriter(FileName, false, Encoding.GetEncoding(EncodingName));
            xmlDocument.Save(sw);
            sw.Close();
        }

        private XmlAttribute CreateAttribute(XmlDocument xmlDocument, string name, string value)
        {
            XmlAttribute xmlAttribute = xmlDocument.CreateAttribute(name);
            xmlAttribute.Value = value;

            return xmlAttribute;
        }

        private void ParseTitle(string title, out string originalTitle, out string translatedTitle, out string formattedTitle)
        {
            originalTitle = translatedTitle = formattedTitle = "";

            string[] titles = title.Split('/');
            if (titles.Length == 1)
            {
                originalTitle = titles[0];
                formattedTitle = titles[0];
            }
            else if (titles.Length > 1)
            {
                translatedTitle = titles[0];
                originalTitle = titles[1];
                formattedTitle = string.Format("{0} ({1})", titles[0], titles[1]);
            }
        }

        private string GenerateList(ArrayList list)
        {
            StringBuilder sb = new StringBuilder();
            foreach (NamedEntity namedEntity in list)
            {
                if (sb.Length > 0)
                {
                    sb.Append("; ");
                }
                sb.Append(namedEntity.Name);
            }
            return sb.ToString();
        }

        private string FormatDescription(string description)
        {
            if (!string.IsNullOrEmpty(description))
            {
                return description.Replace("\n", "|");
            }
            return description;
        }

    }
}
